﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using iMon.DisplayApi;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace DVBViMon
{
    public partial class ScrollTextTimerLCD : System.Windows.Forms.Timer
    {
        #region properties

        public bool LcdScrollDone { get; set; }

        #endregion

        #region enums

        public enum ScrollStates
        {
            WaitLineScrollFinished,
            Pause
        }

        #endregion

        #region fields

        private ScrollStates scrollState = ScrollStates.WaitLineScrollFinished;
        private bool timerLoopActive;
        private string ScrollingTextLine = string.Empty;
        private int ScrollRepeatCounter;
        private FormMain formMain;

        private const int MaxWaitTicks = 3;
        private int waitTickCounter = 0;
        private bool ContinuousScrolling;

        #endregion

        #region ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="ScrollTextTimerLCD"/> class.
        /// </summary>
        /// <param name="interval">The time interval for checking LCD scroll finished.</param>
        public ScrollTextTimerLCD(FormMain formMain, int interval = 500)
        {
            this.LcdScrollDone = false;
            this.Interval = interval;
            this.formMain = formMain;

            InitializeComponent();

            formMain.LCDScrollFinished += mainForm_LCDScrollFinished;
        }
        #endregion

        #region events

        private void mainForm_LCDScrollFinished(object obj, EventArgs e)
        {
            this.LcdScrollDone = true;
        }

        #endregion

        #region overrides

        protected override void OnTick(EventArgs e)
        {
            if (!this.timerLoopActive)
            {
                this.timerLoopActive = true;
                this.DoTheScrolling();
                this.timerLoopActive = false;
            }

            base.OnTick(e);
        }

        #endregion

        #region implementation

        /// <summary>
        /// Does the scrolling. Checks scrollingDone and 
        /// </summary>
        private void DoTheScrolling()
        {
            if (!this.ContinuousScrolling)
                if (this.ScrollRepeatCounter == 0)
                {
                    this.Stop();
                    return;
                }

            switch (this.scrollState)
            {
                case ScrollStates.WaitLineScrollFinished:
                    if (this.LcdScrollDone)
                    {
                        this.scrollState = ScrollStates.Pause;
                        this.waitTickCounter = MaxWaitTicks;
                    }
                    break;

                case ScrollStates.Pause:
                    if (waitTickCounter != 0)
                    {
                        waitTickCounter--;
                    }
                    else
                    {
                        if (!this.ContinuousScrolling)
                        {
                            this.ScrollRepeatCounter--;
                            if (this.ScrollRepeatCounter == 0)
                                this.Stop();
                        }
                        else
                        {
                            LcdScrollDone = false;
                            this.OutLine(ScrollingTextLine);
                            this.scrollState = ScrollStates.WaitLineScrollFinished;
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// Out first 16 characters of line.
        /// </summary>
        /// <param name="line">The line.</param>
        private void OutLine16(string line)
        {
            try
            {
                iMonNativeApi.IMON_Display_SetLcdText(line.Substring(0, 16 ));
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// Sets the LCD text.
        /// </summary>
        /// <param name="line">The line to be shown on the LCD display.</param>
        public void SetLcdText( string line )
        {
            this.Stop();
            this.ScrollingTextLine = line;
            this.ScrollRepeatCounter = Properties.Settings.Default.ScrollRepeat;
            this.ContinuousScrolling = Properties.Settings.Default.continuousScrolling;
            LcdScrollDone = false;
            this.OutLine(line);
            this.scrollState = ScrollStates.WaitLineScrollFinished;
            this.Start();
        }

        private void OutLine(string line)
        {
            try
            {
                iMonNativeApi.IMON_Display_SetLcdText(line.Substring(0,
                                                                     line.Length < 256
                                                                         ? line.Length
                                                                         : 256));
            }
            catch (Exception)
            {
            }
        }

        #endregion
    }
}
